﻿using BZ.Logger;
using HslCommunication;
using HslCommunication.Profinet.Omron;
using NDK.AcqDevice.Gocator;
using NDK.AcqDevice.HikVision;
using NDK.Frm;
using NDK.Laser.SSZN;
using NDK.Module.BLL;
using NDK.Module.StationLogic;
using NDK.Utils;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using static NDK.Frm.Frm_Main;
using static NDK.Module.BLL.Configuration;

namespace NDK.Module.Model
{
    #region 窗体动画效果相关常量
    public enum WindowsEffect
    {
        AW_SLIDE = 0x40000,//使用滑动类型。缺省则为滚动动画类型。当使用AW_CENTER标志时，这个标志就被忽略。    
        AW_ACTIVATE = 0x20000,//激活窗口。在使用了AW_HIDE标志后不要使用这个标志。    
        AW_BLEND = 0x80000,//使用淡出效果。只有当hWnd为顶层窗口的时候才可以使用此标志。    
        AW_HIDE = 0x10000,//隐藏窗口，缺省则显示窗口。(关闭窗口用)    
        AW_CENTER = 0x0010,//若使用了AW_HIDE标志，则使窗口向内重叠；若未使用AW_HIDE标志，则使窗口向外扩展。    
        AW_HOR_POSITIVE = 0x0001,//自左向右显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时，该标志将被忽略。    
        AW_VER_POSITIVE = 0x0004,//自顶向下显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时，该标志将被忽略。    
        AW_HOR_NEGATIVE = 0x0002,//自右向左显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时，该标志将被忽略。    
        AW_VER_NEGATIVE = 0x0008//自下向上显示窗口。该标志可以在滚动动画和滑动动画中使用。当使用AW_CENTER标志时，该标志将被忽略。    
    }
    #endregion

    #region 登陆模式
    public enum LoginMode
    {
        PRODUCTION_MODE = 0,
        ENGINEERING_MODE = 1,
        CPKGRR_MODE = 2
    }
    public enum UserAuthority
    {
        删除用户 = 0,
        添加用户 = 1,
        设置页查看 = 2,
        查看视觉页,
        编辑点位,
        编辑回零,
        添加项目,
        删除项目,
        编辑参数页
    }
    #endregion

    #region Excel输出格式
    public enum SaveDataFormat
    {
        XLS = 0,
        CSV = 1,
        XLSX = 2
    }
    #endregion

    public static class Common
    {
        //软件语言
        public static Dictionary<string, string> languageDic = new Dictionary<string, string>();
        public static Configuration.Language currentLanguage = Language.Chinese;

        //版本信息
        public static string currentVersion = "V1.4.3.220406";

        //离线模式
        public static bool IsOfflineMode;

        //数据库
        public static string DatabasePath = Environment.CurrentDirectory + @"\\Config";
        public static string DatabaseName = "test1";

        //点检
        public static event Action<string> CheckTimeRefreshAction;
        public static bool PointCheck_Block = false;
        public static bool PointCheck_ProductGRR = false;
        public static DataTable GRRPointCheckTable = null;
        public static string pointCheckPath = Environment.CurrentDirectory + "\\Config\\Config";

        //Machine
        public static bool IsIniSucess = false;
        public static bool isCardInitialed = false;
        public static bool isFingerPrintInitialed = false;

        //data
        public static string dataSavePath = @"D:\Data\output";
        public static string picSavePath = @"F:\Data\image";
        public static string pointCheckEncrypterPath = @"D:\Data\output\temp\点检";

        //数据处理
        public static ConcurrentQueue<MeasureProduct> Queue_SaveCsv = new ConcurrentQueue<MeasureProduct>();

        //计数
        public static int OKCount = 0;
        public static int NGCount = 0;
        public static int NACount = 0;
        public static int ExceptionCount = 0;
        public static int TotalCount = 0;

        //Program是否在运行
        public static Stopwatch CT = new Stopwatch();
        public static string ProjectName = "";
        public static string startDate = DateTime.Now.ToString("yyyy-MM-dd");
        public static string startTime = DateTime.Now.ToString("HH:mm:ss");

        //login
        public static string username = "";
        public static string password = "";

        //PLCAdress
        public static PLCAdress PLCAdr { get; set; } = new PLCAdress();

        //PLC报警等级
        public static bool Alarm_PLC提示 { get; set; }
        public static bool Alarm_PLC轻报警 { get; set; }
        public static bool Alarm_PLC重报警 { get; set; }

        public static bool Alarm_PLC停机报警;

        //产品类型
        public static int ProductType = -1;//-1正常产品    大中小   3  2  1

        //算子所在路径
        public static string ProcedurePath = "";

        //UIlog
        public static BZLogger AppendUiLog;
        public static BZLogger AppendCtLog00;
        public static BZLogger AppendCtLog01;
        public static BZLogger AppendCtLog02;
        public static BZLogger AppendCtLog03;
        public static BZLogger AppendCtLog04;
        public static BZLogger AppendCtLog05;
        public static BZLogger AppendCtLog06;
        public static BZLogger AppendCtLog07;
        public static BZLogger AppendCtLog08;
        public static BZLogger AppendCtLog09;
        public static BZLogger AppendCtLog10;
        public static BZLogger AppendCtLog11;
        public static BZLogger AppendCtLog12;
        public static BZLogger AppendCtLog13;
        public static BZLogger AppendCtLog14;
        public static BZLogger AppendCtLog15;


        public static TimeSpan CtLook0;
        public static TimeSpan CtLook1;
        public static TimeSpan CtLook2;
        public static TimeSpan CtLook3;
        public static TimeSpan CtLook4;
        public static TimeSpan CtLook5;
        public static TimeSpan CtLook6;
        public static TimeSpan CtLook7;
        public static TimeSpan CtLook8;
        public static TimeSpan CtLook9;
        public static TimeSpan CtLook10;
        public static TimeSpan CtLook11;
        public static TimeSpan CtLook12;
        public static TimeSpan CtLook13;
        public static TimeSpan CtLook14;
        public static TimeSpan CtLook15;


        public static Stopwatch sw1 = new Stopwatch();
        public static Stopwatch sw2 = new Stopwatch();
        public static Stopwatch sw3 = new Stopwatch();
        public static Stopwatch sw4 = new Stopwatch();
        public static Stopwatch sw5 = new Stopwatch();
        public static Stopwatch sw6 = new Stopwatch();
        public static Stopwatch sw7 = new Stopwatch();
        public static Stopwatch sw8 = new Stopwatch();
        public static Stopwatch sw9 = new Stopwatch();
        public static Stopwatch sw10 = new Stopwatch();
        public static Stopwatch sw11 = new Stopwatch();
        public static Stopwatch sw12 = new Stopwatch();
        public static Stopwatch sw13 = new Stopwatch();
        public static Stopwatch sw14 = new Stopwatch();
        public static Stopwatch sw15 = new Stopwatch();

        public static void Method_联机模式()
        {
            BP_启用安全门 = false;
            BP_保存图片 = true;
            //BP_启用蜂鸣器 = true;
            BP_UPMES = true;
            BP_屏蔽PLC = false;
            BP_屏蔽下料穴1 = false;
            BP_屏蔽下料穴2 = false;
            BP_Is604 = true; ;
            BP_屏蔽log = false;
            BP_屏蔽信号检测 = false;
            BP_是否无料 = false;
            BP_屏蔽扫码 = false;
            BP_屏蔽算法 = false;
            GRR循环模式 = false;
            量块点检 = false;
            Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[PLCOutPutBool.GRR模式], false);
            ParmRefresh();
        }
        public static void Method_量块点检()
        {
            BP_启用安全门 = false;
            BP_保存图片 = true;
            //BP_启用蜂鸣器 = true;
            BP_UPMES = false;
            BP_屏蔽PLC = false;
            BP_屏蔽下料穴1 = false;
            BP_屏蔽下料穴2 = false;
            BP_Is604 = true; ;
            BP_屏蔽log = false;
            BP_屏蔽信号检测 = false;
            BP_是否无料 = false;
            BP_屏蔽扫码 = true;
            BP_屏蔽算法 = false;

            GRR循环模式 = true;
            Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[PLCOutPutBool.GRR模式], true);
            IP_GRR次数 = 1;
            量块点检 = true;
            ParmRefresh();
        }

        //MES
        public static SunWayMes SwMes { get; set; }

        public static SunWayOEETimeMethod OEETimeMethod { get; set; }
        public static SunWayOEEYieldMethodd OEEYieldMethod { get; set; }
        public static SunWayOEEYieldUpLoadMethod OEEYieldUpLoadMethod { get; set; }

        //硬件实例
        public static List<MvCameraController> HikVisionList;

        public static OmronCipNet OmronPLC = new OmronCipNet("192.168.3.39");
        public static OperateResult opreateResult_Isconnect = new OperateResult();
        public static OperateResult opreateResult = new OperateResult();

        public static GocatorController Lmi_短边前激光 = null;
        public static GocatorController Lmi_短边后激光 = null;
        public static GocatorController Lmi_长边左激光 = null;
        public static GocatorController Lmi_长边右激光 = null;

        public static SRController SSZN_上激光 = null;
        public static SRController SSZN_侧激光 = null;
        public static SRController SSZN_下激光 = null;

        public static KeyenceScanReader ScanReader = new KeyenceScanReader();

        private static bool _GRR循环模式;

        public static bool GRR循环模式
        {
            get { return _GRR循环模式; }
            set
            {
                _GRR循环模式 = value;
                if(value)
                {
                    DicHoleShield.Keys.ToList().ForEach(key => { DicHoleShield[key] = true; });
                    DicHoleShield[1] = false;
                    CurGRR循环次数 = 1;
                }
                //if(Common._CurProType == "Product")
                //{
                //    OmronPLC.Write(PLCAdr.DicOutPutBool[PLCOutPutBool.GRR模式], value);
                //}
            }
        }

        public static bool GRREnd;
        public static int CurGRR循环次数 = 0;
        public static bool GRR工位完成;

        public static bool PPG循环启动;
        public static int PPG循环次数;

        private static string _CurProType;

        public static string CurProType
        {
            get { return _CurProType; }
            set
            {
                _CurProType = value;
                PointCheck_Block = value != "Product";
            }
        }

        public static Action<List<ProductTypeMeasureItemEnable>> UpdateMeasureItemsEnable = null;
        public static string ProTypeIniPath = Application.StartupPath + @"\Config\ProductType.ini";
        public static string ProTypeCsvPath = Application.StartupPath + @"\Config\ProductType.csv";

        public const string Section_ProductTypeConfig = "ProductTypeConfig";
        public const string Section_MeasureItems = "MeasureItems";
        public static List<string> DefaultMeasureItems = new List<string>();
        public static List<ProductTypeMeasureItemEnable> ProductTypeMeasureItemEnableList = new List<ProductTypeMeasureItemEnable>();
        public static ProductTypeMeasureItemEnable CurProTypeMeasureItems = new ProductTypeMeasureItemEnable();

        #region 全局标志位

        //强制ok
        public static bool isForceOK = false;
        public static bool isForceNG = false;
        public static bool isForceORT = false;
        public static bool isForceNA = false;

        public static bool IsEmptyModel { get; set; }

        public static bool AllStationFinish;
        public static bool AllStationCanWork;
        public static bool TurnTableNone;
        private static bool _IsClearModel;

        public static bool IsClearModel
        {
            get { return _IsClearModel; }
            set
            {
                if(_IsClearModel != value)
                {
                    _IsClearModel = value;
                    if(!value)
                    {
                        Common.OmronPLC.Write(Common.PLCAdr.DicOutPutBool[PLCOutPutBool.量测清料完成], false);
                    }
                    else
                    {
                        Station_转盘下料.Instance.IsClearModelDone = false;
                    }
                }
            }
        }


        public static Dictionary<int, bool> DicStationWorkStatus;

        private static readonly object LockSignal = new object();

        public static void ChangeTurnTableStatus (int id, bool status)
        {
            lock(LockSignal)
            {
                DicStationWorkStatus[id] = status;
                AllStationFinish = DicStationWorkStatus.Values.All(x => x == true);
            }
        }

        private static readonly object LockSignal1 = new object();

        public static void ChangeHoleStatus (int id, bool status)
        {
            lock(LockSignal1)
            {
                DicHoleCanWork[id] = status;
                TurnTableNone = DicHoleCanWork.Values.All(x => x == false);
            }
        }

        public static Dictionary<int, bool> DicHoleCanWork;
        public static Dictionary<int, bool> DicHoleShield = new Dictionary<int, bool> { { 1, true }, { 2, true }, { 3, true }, { 4, true }, { 5, true }, { 6, true }, { 7, true }, { 8, true } };

        public static bool 量块点检;
        public static bool IsCheckOK { get; set; }

        public static bool IsHomeFirst;
        public static bool StartOnce = false;



        private static string _上次点检时间;

        public static string 上次点检时间
        {
            get { return _上次点检时间; }
            set
            {
                _上次点检时间 = value;
                CheckTimeRefreshAction?.Invoke(value);
            }
        }
        #endregion

        #region 设置页面参数
        //string
        [Description("线体名称")]
        public static string SP_线体 = "";
        [Description("PPGFAI")]
        public static string SP_PPGFAI = "";
        [Description("PPG1IP")]
        public static string SP_PPGIP1 = "";
        [Description("PPG2IP")]
        public static string SP_PPGIP2 = "";
        [Description("工位3_深视上激光IP")]
        public static string SP_工位3_深视上激光IP = "";
        [Description("工位5_LMI短边前激光IP")]
        public static string SP_工位5_LMI短边前激光IP = "";
        [Description("工位5_LMI短边后激光IP")]
        public static string SP_工位5_LMI短边后激光IP = "";
        [Description("工位6_长边左激光IP")]
        public static string SP_工位6_长边左激光IP = "";
        [Description("工位6_长边右激光IP")]
        public static string SP_工位6_长边右激光IP = "";
        [Description("工位7_深视侧激光IP")]
        public static string SP_工位7_深视侧激光IP = "";
        [Description("深视下激光IP")]
        public static string SP_深视下激光IP = "";
        [Description("上次点检时间")]
        public static string SP_上次点检时间 = "";

        //int
        [Description("报警信息保留时间(天)")]
        public static int IP_报警信息保留时间 = 100;
        [Description("光源打开延时时间(ms)")]
        public static int IP_光源延时 = 100;
        [Description("GRR循环次数")]
        public static int IP_GRR次数 = 9;
        [Description("PPG保压时间(ms)")]
        public static int IP_PPG保压时间 = 9;
        [Description("连续NG报警(次)")]
        public static int IP_连续NG报警 = 3;

        //double
        [Description("PPG穴1补偿")]
        public static double DP_PPG补偿1 = 0;
        [Description("PPG穴2补偿")]
        public static double DP_PPG补偿2 = 0;
        [Description("定位补偿X")]
        public static double DP_定位偏移X = 0;
        [Description("定位补偿Y")]
        public static double DP_定位偏移Y = 0;
        [Description("定位补偿R")]
        public static double DP_定位偏移R = 0;

        //Bool
        [Description("是否启用蜂鸣器")]
        public static bool BP_启用蜂鸣器;
        [Description("是否启用安全门")]
        public static bool BP_启用安全门;
        [Description("是否保存图片")]
        public static bool BP_保存图片;
        [Description("是否屏蔽算法")]
        public static bool BP_屏蔽算法;
        [Description("是否屏蔽PPG")]
        public static bool BP_屏蔽PPG;
        [Description("是否关闭日志")]
        public static bool BP_屏蔽log;
        [Description("是否屏蔽信号检测")]
        public static bool BP_屏蔽信号检测;
        [Description("是否屏蔽PLC")]
        public static bool BP_屏蔽PLC;
        [Description("是否屏蔽扫码")]
        public static bool BP_屏蔽扫码;
        [Description("是否禁用转盘穴1")]
        public static bool BP_转盘穴1;
        [Description("是否禁用转盘穴2")]
        public static bool BP_转盘穴2;
        [Description("是否禁用转盘穴3")]
        public static bool BP_转盘穴3;
        [Description("是否禁用转盘穴4")]
        public static bool BP_转盘穴4;
        [Description("是否禁用转盘穴5")]
        public static bool BP_转盘穴5;
        [Description("是否禁用转盘穴6")]
        public static bool BP_转盘穴6;
        [Description("是否禁用转盘穴7")]
        public static bool BP_转盘穴7;
        [Description("是否禁用转盘穴8")]
        public static bool BP_转盘穴8;
        [Description("是否禁用下料穴1")]
        public static bool BP_屏蔽下料穴1;
        [Description("是否禁用下料穴2")]
        public static bool BP_屏蔽下料穴2;
        [Description("是否无料空跑")]
        public static bool BP_是否无料;
        [Description("是否屏蔽计时")]
        public static bool BP_是否屏蔽计时;
        [Description("是否是604产品")]
        public static bool BP_Is604;
        [Description("是否上传MES")]
        public static bool BP_UPMES;
        [Description("是否连续NG报警")]
        public static bool BP_NGalarm;
        #endregion

        #region 方法

        //界面显示刷新参数
        public static void ParmRefresh ()
        {
            var fields = typeof(Common).GetFields().Where(x => x.Name.Contains("BP_")).ToArray();
            foreach(DataRow item in Frm_Setting.Instance.ParamsBoolDataTable.Rows)
            {
                foreach(var field in fields)
                {
                    var des = field.GetCustomAttribute<DescriptionAttribute>().Description;
                    if(des == item[1].ToString())
                    {
                        item[2] = field.GetValue(null);
                    }
                }
            }
            Frm_Setting.Instance.ParamsBoolDataAdapter.Update(Frm_Setting.Instance.ParamsBoolDataTable);
        }

        //克隆数据
        public static MeasureProduct CloneTempData (ref MeasureProduct src, bool isEmptySrc = true)
        {
            MeasureProduct dst = new MeasureProduct()
            {
                SN = src.SN,
                TurnTableHole = src.TurnTableHole,
                NG_FAI = src.NG_FAI,
                MeasureData = src.MeasureData,
                Result = src.Result,
            };
            if(isEmptySrc)
                src = null;
            return dst;
        }
        #endregion

        #region 指纹锁
        public static string fingerPrintAuthority = "";
        public static string fingerPrintUserName = "";
        public static Dlg_AddUeserUI AddUeserUI = new Dlg_AddUeserUI();
        public static string Authority = ""; //登陆用户的权限
        public static bool b_FPLoginClick = false;
        public static bool b_ModifyROIButtonClick = false;
        public static bool b_SaveROIButtonClick = false;
        //public static BioneFPAPILib.FPAPICtrlClass fp; //初始化指纹锁
        public static bool isFileSetPassCode = false;//是否文件夹已经加密，默认是加密状态
        public static FignerPrintForm FPForm = new FignerPrintForm();
        public static int Id = 0;
        public static bool LogIn_TimeOut = false; //登录超时
        public volatile static UserOptionCheckBFMessage msg = null;
        public struct FPUserInfo
        {
            public static string UserName;   //用户名
        }
        #endregion

        #region 暂未使用
        public static PrjPara pPrjPara;
        public static string PathLog = Application.StartupPath + @"\DalsaCam\";
        public static string PathConfig = @"D:\Data\Config\BZ-Parameter\PFA\";
        #endregion
    }

    public class ProductTypeMeasureItemEnable
    {
        public string ProductType { get; set; }


        public Dictionary<string, bool> MeasureItemEnableDic { get; set; }

        public ProductTypeMeasureItemEnable ()
        {
            ProductType = "";
            MeasureItemEnableDic = new Dictionary<string, bool>();
        }
    }
}
